/************************************
 * 本文件用于封装epoll的相关接口函数
 **************************************/
#pragma once
#include <iostream>
#include <string>

#include <cerrno>
#include <cstring>
#include <cstdlib>

#include <sys/epoll.h>

#include "Socket.hpp"
#include "Log.hpp"
#include "Common.h"

namespace MyEpoller
{
    const static int epoll_create_size = 128;
    const static int timeout = 1000;
    class Epoller
    {
    public:
        Epoller()
            : _op(0), _timeout(timeout)
        {
            // 在创建该类对象时，直接创建epoll模型，得到epoll_fd
            _epoll_fd = epoll_create(epoll_create_size);
            if (_epoll_fd == -1)
            {
                _log.LogMessage(ClassFile, Error, "epoll_create error, strerror : %s\n", strerror(errno));
                exit(Epoll_Create_Error);
            }
            _log.LogMessage(ClassFile, Info, "epoll_create success\n");
        }
        ~Epoller()
        {
            close(_epoll_fd); // 忘记了，下次要记住
        }
        // 添加一个事件
        void AddEvent(int fd)
        {
            _op = EPOLL_CTL_ADD;
            epoll_event epevent;
            epevent.events = EPOLLIN;
            epevent.data.fd = fd;
            int ret = epoll_ctl(_epoll_fd, _op, fd, &epevent);
            if(ret == -1)
            {
                _log.LogMessage(ClassFile, Error, "epoll_ctl error, 错误原因 : %s", strerror(errno));
                exit(Epoll_Ctl_Error);
            }
        }
        // 删除一个事件
        void DelEvent(int fd)
        {
            _op = EPOLL_CTL_DEL;
            int ret = epoll_ctl(_epoll_fd, _op, fd, nullptr);
            if(ret == -1)
            {
                _log.LogMessage(ClassFile, Error, "epoll_ctl error, 错误原因 : %s", strerror(errno));
                exit(Epoll_Ctl_Error);
            }
        }
        // epoll等待事件就绪
        int Wait(epoll_event *events, int maxevents)
        {
            return epoll_wait(_epoll_fd, events, maxevents, _timeout);
        }

    private:
        int _epoll_fd;
        int _op; // 对一个fd的event的操作：增删改
        int _timeout;
    };
}